package vip.george.sentinel2.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import vip.george.common.dto.ResultVO;
import vip.george.sentinel2.service.PayService;

/**
 * @author george
 * @since 2023/7/7
 * <p>流控测试</p>
 */

@RestController
@RequestMapping("/flow")
public class FlowTestController {

    @Autowired
    private PayService payService;


    @GetMapping("/add")
    @SentinelResource(value = "add", blockHandler = "afterBlock")
    public ResultVO<String> add(){
        System.out.println("创建支付订单");
        return ResultVO.success("add success");
    }


    /**
     * 目的；为了避免下单时查询订单对系统资源的占用，期望在下单的时候对查询进行限流
     * 做法：对查询资源query进行"关联限流",关联资源为add
     * @return
     */
    @GetMapping("/query")
    @SentinelResource(value = "query", blockHandler = "afterBlock")
    public ResultVO<String> query(){
        System.out.println("查询一个支付订单");
        return ResultVO.success("query success");
    }


    /**
     * 资源被限制的后置执行方法
     * @param ex
     * @return
     */
    public ResultVO<String> afterBlock(BlockException ex){

        if (ex instanceof FlowException) {
            System.out.println();
            return ResultVO.error("资源被限流");
        } else if (ex instanceof DegradeException) {
            System.out.println();
            return ResultVO.error("资源被熔断降级");
        } else if (ex instanceof SystemBlockException) {
            System.out.println();
            return ResultVO.error("系统自适应保护");
        }
        return ResultVO.error("block exception 异常");
    }


    @GetMapping("/pay1")
    public ResultVO<String> pay1(){
        System.out.println("支付接口1");
        String result = payService.pay(1L);
        return ResultVO.success(result);
    }


    @GetMapping("/pay2")
    public ResultVO<String> pay2(){
        System.out.println("支付接口2");
        String result = payService.pay(2L);
        return ResultVO.success(result);
    }
}
